object Book {
  def apply(bookTitle: String, author: String, ISBN: String): Book = new Book(bookTitle, author, ISBN)
  def unapply(book: Book): Option[(String, String, String)] = Some((book.bookTitle, book.author, book.ISBN))
}

class Book(private val bookTitle: String, private val author: String, private val ISBN: String) {
  private var isLoanedOut: Boolean = false

  def loanOut(): Unit = {
    if (isLoanedOut) {
      throw new Exception("This book is already on loan.")
    } else {
      isLoanedOut = true
    }
  }

  def returnBook(): Unit = {
    if (!isLoanedOut) {
      throw new Exception("This book has not been loaned out.")
    } else {
      isLoanedOut = false
    }
  }
}

class Library {
  private var availableBooks: List[Book] = List()
  private var loanedOutBooks: List[Book] = List()

  def addBook(book: Book): Unit = {
    availableBooks = book :: availableBooks
  }

  def loanOutBook(book: Book): Unit = {
    book.loanOut()
    availableBooks = availableBooks.filter(_ != book)
    loanedOutBooks = book :: loanedOutBooks
  }

  def returnBook(book: Book): Unit = {
    book.returnBook()
    loanedOutBooks = loanedOutBooks.filter(_ != book)
    availableBooks = book :: availableBooks
  }
}